#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <vector>

const int num = 10;

void* threadRun(void* agrs)
{
    pthread_detach(pthread_self());
    std::string name = static_cast<const char*>(agrs);
    while(1)
    {
        std::cout << name << " is running..." << std::endl;
        sleep(1);
    }
    
    //return nullptr;
    pthread_exit(agrs);
}

// 问题5：线程的终止
// a.return 函数结束
// b.exit 是专门用来终止进程的，不能用来终止线程。任意线程调用，都会导致进程的终止。
int main()
{
    // 1.线程的id
    std::vector<pthread_t> tds;
    for(int i = 0; i < num; i++)
    {
        pthread_t tid;
        // 2.线程的名字
        char* name = new char[64];
        snprintf(name, 64, "thread-%d", i+1);
        pthread_create(&tid, nullptr, threadRun, /*线程名字*/name);

        // 3.保存线程的id
        tds.push_back(tid);
    }

    sleep(5);
    // 4.等待所有线程
    // for(auto tid: tds)
    // {
    //     pthread_cancel(tid); // 在回收之前取消线程
    //     void* res = nullptr; // 线程被取消，退出结果是-1
    //     pthread_join(tid, &res);
    //     //std::cout << "main thread wait success!" << std::endl;
    //     std::cout << "main thread wait success!" << (long long int)res << " quit..." << std::endl;

    // }
    return 0;
}

////////////////////////////////////////////////////////////////////////////////////////
// 问题4：创建多线程
// int main()
// {
//     // 1.线程的id
//     std::vector<pthread_t> tds;
//     for(int i = 0; i < num; i++)
//     {
//         pthread_t tid;
//         // 2.线程的名字
//         char* name = new char[64];
//         snprintf(name, 64, "thread-%d", i+1);
//         pthread_create(&tid, nullptr, threadRun, /*线程名字*/name);

//         // 3.保存线程的id
//         tds.push_back(tid);
//     }

//     //
//     //sleep(100);
//     // 4.等待所有线程
//     for(auto tid: tds)
//     {
//         pthread_join(tid, nullptr);
//         std::cout << "main thread wait success!" << std::endl;
//     }
//     return 0;
// }

/////////////////////////////////////////////////////////////////////////////////////
// class ThreadDate
// {
// public:
//     std::string name;
//     int num;
// };

// // 新线程
// // 问题3：线程的返回
// // 线程的返回值只有正确执行完程序的返回值，一旦出现异常(野指针/除0)，整个进程都会崩掉
// // 那么就连错误返回的机会都没有了。
// void *threadHandler(void *args)
// {
//     //std::string name = (const char*)args;
//     ThreadDate* td = static_cast<ThreadDate*>(args);

//     int cnt = 5;
//     while (cnt--)
//     {
//         sleep(1);
//         //std::cout << name << " running..., cnt: " << cnt << std::endl;
//         std::cout << td->name << " running..., cnt: " << cnt << "num is " <<  td->num << std::endl;

//     }
//     delete td;
//     return (void*)1111;
// }


// int main()
// {
//     pthread_t tid;
//     // 问题1：main和new线程谁先执行？ 不确定
//     // 问题2：第四个参数，可以是任意类型的，内置类型或是类对象的地址!
//     // 但是不推荐直接在main函数栈上定义对象，避免多线程时有些线程修改值，发生混乱。
//     // ThreadDate td;
//     // td.name = "new-thread";
//     // td.num = 1;

//     //int n =pthread_create(&tid, nullptr, threadHandler, (void *)&td);

//     // 建议在堆上new一个，这样每个线程都有独立的空间了
//     ThreadDate* td = new ThreadDate();
//     td->name = "new-thread";
//     td->num = 1;

//     int n =pthread_create(&tid, nullptr, threadHandler, td);
//     if(n != 0)
//     {
//         std::cerr << "create thread failed!" << std::endl;
//         return -1;
//     }
//     std:: cout << "main thread join begin..." << std::endl;

//     // 主线程
//     // 如果新线程不退，主线程会一直阻塞join，如果不join，会造成类似"僵尸进程"的问题
//     void* ret = nullptr; // 类似于获取进程的退出信息
//     n = pthread_join(tid, &ret);
//     if(n == 0)
//     {
//         std::cout << "main thread wait success! new thread exit code: " << (uint64_t)ret << std::endl;
//     }

//     return 0;
// }